package process

import (
	"dmsv/agent"
	"dmsv/common"
	ss "dmsv/session"
	"fmt"
	"github.com/beego/beego/v2/core/logs"
	"time"
)

func callbackProcess(agent *agent.AgentInfo, msgChan chan *ss.CallBackData, callback string) {

	callAnswer := 0
	duration := 0
	var evSession *ss.SessionInfo
	rs := common.StatusCode{}

Loop:
	for {
		ev := <-msgChan
		logs.Debug("[%v]receive result:%v", ev.CallId, ss.ConvertCallStatusToString(ev.Event))

		evSession = ev.Ssion
		switch ev.Event {
		case ss.CALL_EVENT_START:

		case ss.CALL_EVENT_FAIL:
			//呼叫失败
			if ev.Data != nil {
				rs = ev.Data.(common.StatusCode)
			} else {
				rs = common.ErrSystem
			}

			rs.Answer = false

			break Loop

		case ss.CALL_EVENT_ANSWER:

			callAnswer++
			//坐席接听 启动录音
			if ev.Dir == ss.LEG_DIR_SERVICE {
				fileName := createRecordName(ev.CallId, ev.Caller, ev.Callee)
				ev.Ssion.StartRecord(fileName)
				logs.Debug("[%v] %v is answerd,start call user[%v]", ev.CallId, ev.Dir, ev.Callee)

				//呼叫用户
				ev.Ssion.BridgeCallUser()
			}

		case ss.CALL_EVENT_HANGUP:

			hangUp := ev.Data.(*ss.HangInfo)
			//details = append(details, result.Call)

			if rs.Code == "" {
				if callAnswer > 1 {
					//用户接听的情况
					if ev.Dir == ss.LEG_DIR_USER {
						//record = hangUp.Record
						rs = common.ErrCalleeHangup
					} else if ev.Dir == ss.LEG_DIR_SERVICE {
						rs = common.ErrCallerHangup
					}
				} else if callAnswer == 1 {
					if ev.Dir == ss.LEG_DIR_USER {
						if hangUp.Dir == ss.HANG_UP_LINEERR {
							rs = common.ErrCallLineErr
						} else {
							rs = common.ErrCalleeUnAnswer
						}
					} else {
						rs = common.ErrCancelByCaller
					}
				} else {
					if hangUp.Dir == ss.HANG_UP_LINEERR {
						rs = common.ErrCallerLineErr
					} else {
						rs = common.ErrUnAnswer
					}
				}
			}

			//任意一路电话挂断，均终止通话
			break Loop
		}
	}

	//延时发送话单，以解决单路挂断的情况下，话单信息未同步的情况
	time.Sleep(1 * time.Second)

	if callback != "" {
		//发送给客户回调
		evSession.SendBill(callback, rs)
	}
	evSession.SendBill(gCallBack, rs)

	agent.SetPhoneFree(duration, false)
	logs.Debug("[%v] call back finished", evSession.GetSessionId())
}

func CallBackService(appId, service, callee, display, callBack string) (string, error) {

	s, err := agent.GetAgentInfo(service)
	if err != nil {
		logs.Warn("service %v  not sign in,search appId + service:%v", service, appId+service)
		s, err = agent.GetAgentInfoByService(appId, service)
		if err != nil {
			logs.Error("appId:%v service %v  not sign in. 外呼失败", appId, service)
			return "", fmt.Errorf("坐席未签入")
		}
	}

	if s.IsBusy() {
		logs.Error("appId:%v service %v  正忙", appId, service)
		return "", fmt.Errorf("%v 坐席正忙", service)
	}

	s.SetPhoneBusy()

	callId := createUUid()
	cbChan := make(chan *ss.CallBackData, 20)

	if display == "" {
		display, err = GetDisplay(appId)
		if err != nil {
			return "", fmt.Errorf("没有外显号")
		}
	}

	//呼叫坐席
	err = ss.CallBackService(s, callId, callee, display, cbChan)
	if err != nil {
		logs.Error("创建呼叫失败")
		return "", err
	}

	go callbackProcess(s, cbChan, callBack)
	return callId, nil
}
